What is node-watch?
The node-watch package is a simple and efficient file system watcher for Node.js. It allows you to monitor changes in files and directories, making it useful for tasks such as live-reloading, automated testing, and more.
What are node-watch's main functionalities?
Watch a single file
This feature allows you to watch a single file for changes. The callback function is triggered whenever the file is modified.
const watch = require('node-watch');
watch('file.txt', { recursive: false }, function(evt, name) {
console.log('%s changed.', name);
});
Watch a directory recursively
This feature allows you to watch a directory and all its subdirectories for changes. The callback function is triggered whenever any file within the directory or its subdirectories is modified.
const watch = require('node-watch');
watch('directory', { recursive: true }, function(evt, name) {
console.log('%s changed.', name);
});
Filter files to watch
This feature allows you to specify a filter to watch only certain types of files. In this example, only JavaScript files within the directory are monitored for changes.
const watch = require('node-watch');
watch('directory', { filter: /\.js$/ }, function(evt, name) {
console.log('%s changed.', name);
});
Other packages similar to node-watch
chokidar
Chokidar is a highly efficient and feature-rich file system watcher for Node.js. It supports recursive watching, filtering, and more advanced features like debouncing and throttling. Compared to node-watch, Chokidar offers more configuration options and better performance for large-scale projects.
gaze
Gaze is another file watcher for Node.js that supports recursive watching and filtering. It is known for its simplicity and ease of use. While it offers similar functionalities to node-watch, it may not be as performant or feature-rich as Chokidar.
watch
The watch package is a simple file watcher for Node.js. It provides basic functionality for monitoring file changes but lacks some of the advanced features found in Chokidar and node-watch. It is suitable for smaller projects or simpler use cases.
node-watch
A wrapper and enhancements for fs.watch.
Installation
npm install node-watch
Example
var watch = require('node-watch');
watch('file_or_dir', { recursive: true }, function(evt, name) {
console.log('%s changed.', name);
});
Now it's fast to watch deep directories on macOS and Windows, since the recursive
option is natively supported except on Linux.
watch('/', { recursive: true }, console.log);
Why?
- Some editors will generate temporary files which will cause the callback function to be triggered multiple times.
- The callback function will only be triggered once on watching a single file.
Missing an option to watch a directory recursively.- Recursive watch is not supported on Linux or in older versions of nodejs.
- Keep it simple, stupid.
Options
The usage and options of node-watch
are compatible with fs.watch.
persistent: Boolean
(default true)recursive: Boolean
(default false)encoding: String
(default 'utf8')
Extra options
-
filter: RegExp | Function
Return that matches the filter expression.
watch('./', { filter: /\.json$/ });
watch('./', { filter: f => !/node_modules/.test(f) });
Each file and directory will be passed to the filter to determine whether
it will then be passed to the callback function. Like Array.filter
does in JavaScript
.
There are three kinds of return values for filter function:
true
: Will be passed to callback.false
: Will not be passed to callback.skip
: Same with false
, and skip to watch all its subdirectories.
On Linux, where the recursive
option is not natively supported,
it is more efficient to skip ignored directories by returning the skip
flag:
watch('./', {
recursive: true,
filter(f, skip) {
if (/\/node_modules/.test(f)) return skip;
if (/\.git/.test(f)) return skip;
return /\.js$/.test(f);
}
});
If you prefer glob patterns you can use minimatch or picomatch
together with filter:
const pm = require('picomatch');
let isMatch = pm('*.js');
watch('./', {
filter: f => isMatch(f)
});
-
delay: Number
(in ms, default 200)
Delay time of the callback function.
watch('./', { delay: 5000 }, console.log);
Events
The events provided by the callback function is either update
or remove
, which is less confusing to fs.watch
's rename
or change
.
watch('./', function(evt, name) {
if (evt == 'update') {
}
if (evt == 'remove') {
}
});
Watcher object
The watch function returns a fs.FSWatcher like object as the same as fs.watch
(>= v0.4.0).
Watcher events
let watcher = watch('./', { recursive: true });
watcher.on('change', function(evt, name) {
});
watcher.on('error', function(err) {
});
watcher.on('ready', function() {
});
Close
watcher.close();
watcher.isClosed()
List of methods
.on
.once
.emit
.close
.listeners
.setMaxListeners
.getMaxListeners
.isClosed
detect if the watcher is closed.getWatchedPaths
get all the watched paths
Known issues
Windows, node < v4.2.5
- Failed to detect
remove
event - Failed to get deleted filename or directory name
MacOS, node 0.10.x
- Will emit double event if the directory name is of one single character.
Misc
1. Watch multiple files or directories in one place
watch(['file1', 'file2'], console.log);
2. Customize watch command line tool
#!/usr/bin/env node
require('epipebomb')();
let watcher = require('node-watch')(
process.argv[2] || './', { recursive: true }, console.log
);
process.on('SIGINT', watcher.close);
Monitoring chrome from disk:
$ watch / | grep -i chrome
3. Got ENOSPC error?
If you get ENOSPC error, but you actually have free disk space - it means that your OS watcher limit is too low and you probably want to recursively watch a big tree of files.
Follow this description to increase the limit:
https://confluence.jetbrains.com/display/IDEADEV/Inotify+Watches+Limit
Alternatives
Contributors
Thanks goes to all wonderful people who have helped this project.
License
MIT
Copyright (c) 2012-2021 yuanchuan